home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
ADA
/
GNAT
/
!gcc
/
adainc
/
4
/
adb
/
s-finimp
< prev
next >
Wrap
Text File
|
1996-02-12
|
8KB
|
245 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S Y S T E M . F I N A L I Z A T I O N _ I M P L E M E N T A T I O N --
-- --
-- B o d y --
-- --
-- $Revision: 1.23 $ --
-- --
-- Copyright (C) 1992,1993,1994,1995 Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
-- MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- this unit does not by itself cause the resulting executable to be --
-- covered by the GNU General Public License. This exception does not --
-- however invalidate any other reasons why the executable file might be --
-- covered by the GNU Public License. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
-- --
------------------------------------------------------------------------------
with Ada.Exceptions;
with Ada.Finalization;
with Ada.Finalization.List_Controller;
with Ada.Unchecked_Conversion;
with System.Storage_Elements;
package body System.Finalization_Implementation is
use Ada.Finalization;
use Ada.Finalization.List_Controller;
use Ada.Exceptions;
use System.Finalization_Root;
use System.Storage_Elements;
--------------------------
-- Attach_To_Final_List --
--------------------------
procedure Attach_To_Final_List
(L : in out Finalizable_Ptr;
Obj : in out Finalizable)
is
Obj_Ref : constant Finalizable_Ptr := Obj'Unchecked_Access;
begin
if L = null then
Obj.Next := null;
Obj.Prev := null;
L := Obj_Ref;
-- First attachment on a list of dynamically allocated objects. The
-- access to the list_controller is kept in the PREV of the first
-- element.
elsif Is_Empty_List_Controller (L) then
Obj.Next := null;
Obj.Prev := L;
L := Obj_Ref;
else
Obj.Next := L;
Obj.Prev := L.Prev;
L.Prev := Obj_Ref;
L := Obj_Ref;
end if;
end Attach_To_Final_List;
----------------------------
-- Detach_From_Final_List --
----------------------------
procedure Detach_From_Final_List (Obj : in out Finalizable) is
begin
if Obj.Prev = null then
null; -- should not happen
-- when it is the first of a chain of dynamically-allocated object,
-- L may not be the right pointer since the allocation and the
-- deallocation can be done with 2 different compatible general
-- access types
elsif Is_List_Controller (Obj.Prev) then
Update_List_Controller (Obj.Prev, Obj.Next);
else
Obj.Prev.Next := Obj.Next;
end if;
if Obj.Next /= null then
Obj.Next.Prev := Obj.Prev;
Obj.Next := null;
end if;
Obj.Prev := null;
end Detach_From_Final_List;
-------------------
-- Finalize_List --
-------------------
procedure Finalize_List (L : Finalizable_Ptr) is
P : Finalizable_Ptr := L;
Q : Finalizable_Ptr;
begin
while P /= null loop
Q := P.Next;
Finalize (P.all);
P := Q;
end loop;
exception
when E_Occ : others =>
Finalize_List (Q);
Raise_Exception (
E => Program_Error'Identity,
Message => "exception "
& Exception_Name (E_Occ) & " raised during finalization");
end Finalize_List;
--------------------------
-- Finalize_Global_List --
--------------------------
procedure Finalize_Global_List is
begin
Finalize_List (Global_Final_List);
end Finalize_Global_List;
------------------
-- Finalize_One --
------------------
procedure Finalize_One (Obj : in out Finalizable) is
begin
Detach_From_Final_List (Obj);
Finalize (Root_Controlled'Class (Obj));
exception
when E_Occ : others =>
Raise_Exception (
E => Program_Error'Identity,
Message => "exception "
& Exception_Name (E_Occ) & " raised during finalization");
end Finalize_One;
----------------------------------
-- Record_Controller Management --
----------------------------------
----------------
-- Initialize --
----------------
procedure Initialize (Object : in out Limited_Record_Controller) is
begin
null;
end Initialize;
procedure Initialize (Object : in out Record_Controller) is
begin
Object.My_Address := Object'Address;
end Initialize;
-------------
-- Adjust --
-------------
procedure Adjust (Object : in out Record_Controller) is
My_Offset : constant Storage_Offset
:= Object.My_Address - Object'Address;
P : Finalizable_Ptr;
procedure Ptr_Adjust (Ptr : in out Finalizable_Ptr);
-- Substract the offset to the pointer
procedure Reverse_Adjust (P : Finalizable_Ptr);
-- Ajust the components in the reverse order in which they are stored
-- on the finalization list. (Adjust and Finalization are not done in
-- the same order)
procedure Ptr_Adjust (Ptr : in out Finalizable_Ptr) is
function To_Addr is
new Ada.Unchecked_Conversion (Finalizable_Ptr, Address);
function To_Ptr is
new Ada.Unchecked_Conversion (Address, Finalizable_Ptr);
begin
if Ptr /= null then
Ptr := To_Ptr (To_Addr (Ptr) - My_Offset);
end if;
end Ptr_Adjust;
procedure Reverse_Adjust (P : Finalizable_Ptr) is
begin
if P /= null then
Ptr_Adjust (P.Next);
Ptr_Adjust (P.Prev);
Reverse_Adjust (P.Next);
Adjust (P.all);
end if;
end Reverse_Adjust;
begin
-- Adjust the components and their finalization pointers next
Ptr_Adjust (Object.F);
Reverse_Adjust (Object.F);
-- then Adjust the object itself
Object.My_Address := Object'Address;
end Adjust;
--------------
-- Finalize --
--------------
procedure Finalize (Object : in out Limited_Record_Controller) is
begin
Finalize_List (Object.F);
end Finalize;
end System.Finalization_Implementation;